package box.data.dbutils;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import box.core.ThinkException;
import box.data.dbutils.handlers.ArrayListHandler;
import box.data.dbutils.handlers.BeanHandler;
import box.data.dbutils.handlers.BeanListHandler;
import box.data.dbutils.handlers.MapHandler;
import box.data.dbutils.handlers.MapListHandler;
import box.data.dbutils.handlers.ScalarHandler;

public class BaseDao {
    private static QueryRunner queryRunner = new QueryRunner();

    @SuppressWarnings("unchecked")
	public static int count(Connection conn, String sql, Object ...params) throws ThinkException {
        Object out;
        try {
            out = queryRunner.query(conn, sql, new ScalarHandler(1), params);
        } catch (SQLException ex) {
            throw ThinkException.SQLException(ex);
        }
        return Integer.parseInt(out.toString());
    }
    
    public static int[] batch(Connection conn, String sql, Object[][] params) throws ThinkException {
        try {
            return queryRunner.batch(conn, sql, params);
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }
    }

    public static int update(Connection conn, String sql, Object ...params) {
        try {
            return queryRunner.update(conn, sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, String> query(Connection conn, String sql, Object ...params) {
        try {
            return set(queryRunner.query(conn, sql, new MapHandler(), params));
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }
    }

    public static List<Map<String, String>> queryList(Connection conn, String sql, Object ...params) {
        try {
            return set(queryRunner.query(conn, sql, new MapListHandler(), params));
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public static Object query(Connection conn, String sql, Class<?> type, RowProcessor rp, Object ...params) {
        try {
            return queryRunner.query(conn, sql, new BeanHandler(type, rp), params);
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }
    }

    @SuppressWarnings("unchecked")
    public static List<?> queryList(Connection conn, String sql, Class<?> type, RowProcessor rp, Object ...params) {
        try {
            return (List<?>) queryRunner.query(conn, sql, new BeanListHandler(type, rp), params);
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }
    }

    public static List<Object[]> queryArrayList(Connection conn, String sql, Object ...params) {
        try {

            return queryRunner.query(conn, sql, new ArrayListHandler(), params);
        } catch (SQLException e) {
            throw ThinkException.SQLException(e);
        }

    }
    
    private static List<Map<String,String>> set(List<Map<String, Object>> result){
    	List<Map<String,String>> list = new ArrayList<Map<String,String>>();
    	if(result!=null && result.size()>0){
    		for(Map<String,Object> map : result)
    			list.add(set(map));
    	}
    	return list;
    }
    
    private static Map<String,String> set(Map<String,Object> map){
    	Map<String,String> result = null;
    	if(map!=null && map.size()>0){
    		result = new HashMap<String, String>();
    		for(Map.Entry<String, Object> entry : map.entrySet()){
    			String key = entry.getKey().toLowerCase();
    			result.put(getItemName(key), dealValue(entry.getValue()));
    		}
    	}
    	return result;
    }
    
    private static String getItemName(String dbKey){
    	if(dbKey!=null && !"".equals(dbKey)){
    		StringBuffer sb = new StringBuffer();
    		char[] chars = dbKey.toCharArray();
    		for(int i=0;i<chars.length;i++){
    			if(i==0){
    				sb.append((""+chars[i]).toUpperCase());
    			}else if(chars[i]=='_'){
    				i++;
    				sb.append(("_"+chars[i]).toUpperCase());
    			}else{
    				sb.append(chars[i]);
    			}
    		}
    		return sb.toString();
    	}
    	return null;
    }
    
    private static String dealValue(Object value){
    	if(value!=null){
    		if(value instanceof Timestamp)
        		return String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", value);
        	
    		if(value instanceof Date)
    			return String.format("%1$tY-%1$tm-%1$td", value);
        	if(value instanceof BigDecimal)
        		return String.format("%.4f",value);
        	
        	return value.toString();
    	}else{
    		return null;
    	}
    	
    }
}
